// noinspection NonAsciiCharacters

import type { ElementSelectorDOMScopeType } from '../types/constants'
import {
  queryHTMLElement,
  queryJQuery,
  queryNodeList,
} from '../lib/element_query'
import { ElementSelectorType, logger } from '../types/constants'
import { SYMBOLS } from '../types/interfaces'

export interface TestElementQueryData {
  domScope?: ElementSelectorDOMScopeType
  hostSelector?: string
  selector: string
  selectorType: ElementSelectorType
  description: string
}

/**
 * 测试元素查询（https://greasyfork.org/zh-CN）
 */
export class TestElementQuery {
  private readonly name: string = 'TestElementQuery'
  static instance: TestElementQuery

  static getInstance(): TestElementQuery {
    if (!TestElementQuery.instance) {
      TestElementQuery.instance = new TestElementQuery()
    }
    return TestElementQuery.instance
  }

  startTest(): void {
    const test_cases: TestElementQueryData[] = [
      {
        selector: '#main-header',
        selectorType: ElementSelectorType.Id,
        description: '测试 ID 选择器',
      },
      {
        selector: '.super-title',
        selectorType: ElementSelectorType.Class,
        description: '测试类名选择器',
      },
      {
        selector: '.browser-list',
        selectorType: ElementSelectorType.Class,
        description: '测试类名选择器（匹配多个）',
      },
      {
        selector: 'header',
        selectorType: ElementSelectorType.Tag,
        description: '测试标签名选择器',
      },
      {
        selector: 'h3',
        selectorType: ElementSelectorType.Tag,
        description: '测试标签名选择器（匹配多个）',
      },
      {
        selector: '[type="search"]',
        selectorType: ElementSelectorType.Attribute,
        description: '测试属性选择器',
      },
      {
        selector: '#home-script-nav .search-submit',
        selectorType: ElementSelectorType.Mix,
        description: '测试混合选择器',
      },
      {
        selector: '.home-search > input[type="search"]',
        selectorType: ElementSelectorType.Complex,
        description: '测试复杂选择器',
      },
      {
        selector: '#home-step-1, #home-step-2',
        selectorType: ElementSelectorType.Multiple,
        description: '测试多个选择器',
      },
      {
        selector: '#home-step-1 p span:contains("桌面端")',
        selectorType: ElementSelectorType.JQuery,
        description: '测试 JQuery 选择器',
      },
    ]

    const data = test_cases.map((test_case) => {
      const { domScope, hostSelector, selector } = test_case

      const nativeStartTime = performance.now()
      const nativeResult = queryHTMLElement(selector, { domScope, hostSelector })
      const nativeTimeCost = performance.now() - nativeStartTime

      const nodeListStartTime = performance.now()
      const nodeListResult = queryNodeList(selector, { domScope, hostSelector })
      const nodeListTimeCost = performance.now() - nodeListStartTime

      const jqueryStartTime = performance.now()
      const jqueryResult = queryJQuery(selector, { domScope, hostSelector })
      const jqueryTimeCost = performance.now() - jqueryStartTime

      const nativeResultHTML = nativeResult?.outerHTML || ''
      const nodeListResultHTML = (nodeListResult && (nodeListResult[0] as HTMLElement)?.outerHTML) || ''
      const jqueryResultHTML = jqueryResult?.[0]?.outerHTML || ''

      const nativeResultCount = nativeResult ? 1 : 0
      const nodeListResultCount = nodeListResult?.length ?? 0
      const jqueryResultCount = jqueryResult?.length ?? 0

      return ({
        选择器类型: test_case.selectorType,
        选择器: test_case.selector,
        测试用例描述: test_case.description,
        原生查询耗时: `${nativeTimeCost.toFixed(2)}ms`,
        节点列表查询耗时: `${nodeListTimeCost.toFixed(2)}ms`,
        JQuery查询耗时: `${jqueryTimeCost.toFixed(2)}ms`,
        原生查询结果: `${nativeResultHTML}`,
        原生查询个数: `${nativeResultCount}个`,
        节点列表查询结果: `${nodeListResultHTML}`,
        节点列表查询个数: `${nodeListResultCount}个`,
        JQuery查询结果: `${jqueryResultHTML}`,
        JQuery查询个数: `${jqueryResultCount}个`,
        结果是否一致: nodeListResultHTML === jqueryResultHTML ? `${SYMBOLS.STATUS.SUCCESS}` : `${SYMBOLS.STATUS.ERROR}`,
        个数是否一致: nodeListResultCount === jqueryResultCount ? `${SYMBOLS.STATUS.SUCCESS}` : `${SYMBOLS.STATUS.ERROR}`,
      })
    })

    logger.table(`[${this.name}] ${SYMBOLS.UI.CHART} 元素查询统计`, data)
  }
}
